#pragma once
#include <iomanip>
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define __CACHE_LINE_SIZE__ 64
//#define __QTS__
#define __COO__
//#define __CSR__
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#ifndef __NOTIMEDRUNS__
#define __SPMV__
#endif
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define FREE( pointer )            free_align( pointer )
#define REALLOC( pointer, size )   realloc_align( pointer, size, __CACHE_LINE_SIZE__ )
#define MALLOC( size )             malloc_align( size, __CACHE_LINE_SIZE__ )
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)>(b)?(b):(a))
//#define roundTo(a,bits) ((((a)+(1<<(bits))-1)>>(bits))<<(bits))
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#include <time.h>
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define SETSTR( w ) std::setw( w ) << std::setfill(' ')
#define SETDEC( w ) std::dec << std::setw( w ) << std::setfill(' ')
#define SETHEX( w ) std::hex << std::setw( w ) << std::setfill('0')
#define SETSCI( w ) std::scientific << std::setprecision( w )
#define SETFIX( w ) std::fixed      << std::setprecision( w )
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define OD 1 // region: on diagonal
#define AD 2 // region: above diagonal
#define BD 4 // region: below diagonal
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#define XDEBUG_PRINT(str) std::cout << std::endl << str; std::cout.flush()
#ifdef  LOCAL_DEBUG_ENABLED
#define ASSERT( x ) assert( x )
#define DEBUG_PRINT_VEC( p, n, s )     for( U32 dbgIdx = 0; dbgIdx < n; dbgIdx++ ) { printf("%s[%d]=%+10.4e\n",            s, dbgIdx, p[   dbgIdx ]                ); }
#define DEBUG_PRINT_INT_VEC( p, n, s ) for( U32 dbgIdx = 0; dbgIdx < n; dbgIdx++ ) { printf("%s[%d]=%d\n",                 s, dbgIdx, p[   dbgIdx ]                ); }
#define DEBUG_PRINT_CV_VEC( p, n, s )  for( U32 dbgIdx = 0; dbgIdx < n; dbgIdx++ ) { printf("%s[%d]=(%+10.4e, %+10.4e)\n", s, dbgIdx, p[ 2*dbgIdx ], p[2*dbgIdx+1] ); }
#define DEBUG_PRINT(str) std::cout << std::endl << str; std::cout.flush()
#define DEBUG_PRINT_NOBREAK(str) std::cout << str; std::cout.flush()
#else
#define ASSERT( x )
#define DEBUG_PRINT_VEC( p, n, s )
#define DEBUG_PRINT_INT_VEC( p, n, s )
#define DEBUG_PRINT_CV_VEC( p, n, s )
#define DEBUG_PRINT(str)
#define DEBUG_PRINT_NOBREAK(str)
#endif /* LOCAL_DEBUG_ENABLED */
